package cn.cyh.queue_service.service.impl;

import cn.cyh.queue_service.common.ResultCode;
import cn.cyh.queue_service.exception.BusinessException;
import cn.cyh.queue_service.mapper.NoticeMapper;
import cn.cyh.queue_service.model.dto.PageRequest;
import cn.cyh.queue_service.model.dto.PageResult;
import cn.cyh.queue_service.model.entity.Notice;
import cn.cyh.queue_service.model.vo.NoticeVO;
import cn.cyh.queue_service.service.NoticeService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 通知公告服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements NoticeService {
    
    private final NoticeMapper noticeMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createNotice(Notice notice) {
        // 验证参数
        if (StrUtil.isBlank(notice.getTitle())) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "通知标题不能为空");
        }
        
        if (StrUtil.isBlank(notice.getContent())) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "通知内容不能为空");
        }
        
        // 设置默认值
        if (notice.getStatus() == null) {
            notice.setStatus(1); // 默认显示
        }
        
        if (notice.getPriority() == null) {
            notice.setPriority(0); // 默认优先级
        }
        
        // 设置时间
        LocalDateTime now = LocalDateTime.now();
        notice.setCreateTime(now);
        notice.setUpdateTime(now);
        
        // 如果开始时间为空，设置为当前时间
        if (notice.getStartTime() == null) {
            notice.setStartTime(now);
        }
        
        // 如果结束时间为空，设置为未来30天
        if (notice.getEndTime() == null) {
            notice.setEndTime(now.plusDays(30));
        }
        
        // 保存通知公告
        save(notice);
        
        return notice.getId();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateNotice(Long id, Notice notice) {
        // 检查通知公告是否存在
        Notice existingNotice = getById(id);
        if (existingNotice == null) {
            throw new BusinessException(ResultCode.NOTICE_NOT_FOUND);
        }
        
        // 设置ID和更新时间
        notice.setId(id);
        notice.setUpdateTime(LocalDateTime.now());
        
        // 更新通知公告
        return updateById(notice);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteNotice(Long id) {
        // 检查通知公告是否存在
        Notice existingNotice = getById(id);
        if (existingNotice == null) {
            throw new BusinessException(ResultCode.NOTICE_NOT_FOUND);
        }
        
        // 执行删除
        return removeById(id);
    }
    
    @Override
    public NoticeVO getNoticeById(Long id) {
        Notice notice = getById(id);
        if (notice == null) {
            throw new BusinessException(ResultCode.NOTICE_NOT_FOUND);
        }
        
        return convertToVO(notice);
    }
    
    @Override
    public PageResult<NoticeVO> getNoticeList(PageRequest pageRequest) {
        IPage<Notice> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
        
        // 构建查询条件
        LambdaQueryWrapper<Notice> queryWrapper = new LambdaQueryWrapper<>();
        
        // 设置排序
        if (StrUtil.isNotBlank(pageRequest.getOrderBy())) {
            queryWrapper.orderBy(true, 
                    pageRequest.getIsAsc(), 
                    "create_time".equals(pageRequest.getOrderBy()) ? Notice::getCreateTime : 
                    "update_time".equals(pageRequest.getOrderBy()) ? Notice::getUpdateTime : 
                    "priority".equals(pageRequest.getOrderBy()) ? Notice::getPriority :
                    Notice::getId);
        } else {
            queryWrapper.orderByDesc(Notice::getPriority, Notice::getCreateTime);
        }
        
        // 执行分页查询
        page = page(page, queryWrapper);
        
        // 转换为VO
        List<NoticeVO> voList = page.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        // 构建分页结果
        return PageResult.<NoticeVO>builder()
                .pageNum(pageRequest.getPageNum())
                .pageSize(pageRequest.getPageSize())
                .total(page.getTotal())
                .pages((int) page.getPages())
                .list(voList)
                .hasPrev(pageRequest.getPageNum() > 1)
                .hasNext(pageRequest.getPageNum() < page.getPages())
                .build();
    }
    
    @Override
    public List<NoticeVO> getActiveNotices() {
        List<Notice> noticeList = noticeMapper.selectActiveNotices();
        
        return noticeList.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<NoticeVO> getHomePageNotices() {
        List<Notice> noticeList = noticeMapper.selectHomePageNotices();
        
        return noticeList.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(Long id, Integer status) {
        // 验证状态值
        if (status != 0 && status != 1) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }
        
        // 检查通知公告是否存在
        Notice existingNotice = getById(id);
        if (existingNotice == null) {
            throw new BusinessException(ResultCode.NOTICE_NOT_FOUND);
        }
        
        // 更新状态
        LambdaUpdateWrapper<Notice> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Notice::getId, id)
                .set(Notice::getStatus, status)
                .set(Notice::getUpdateTime, LocalDateTime.now());
        
        return update(updateWrapper);
    }
    
    /**
     * 将通知公告实体转换为视图对象
     */
    private NoticeVO convertToVO(Notice notice) {
        if (notice == null) {
            return null;
        }
        
        NoticeVO vo = new NoticeVO();
        BeanUtil.copyProperties(notice, vo);
        
        // 判断是否在有效期内
        LocalDateTime now = LocalDateTime.now();
        boolean isActive = notice.getStatus() == 1 && 
                notice.getStartTime().isBefore(now) && 
                notice.getEndTime().isAfter(now);
        
        vo.setIsActive(isActive);
        
        return vo;
    }
}